package others;

public class TestOffer2_103 {
    /**
     * 剑指 Offer II 103. 最少的硬币数目
     * 给定不同面额的硬币 coins 和一个总金额 amount。编写一个函数来计算可以凑成总金额所需的最少的硬币个数。如果没有任何一种硬币组合能组成总金额，返回 -1。
     * 你可以认为每种硬币的数量是无限的。
     * 输入：coins = [1, 2, 5], amount = 11
     * 输出：3
     * 解释：11 = 5 + 5 + 1
     */
    public static  int coinChange(int[] coins, int amount) {
        /**
         * 动态规划思路： 最少硬币数 = amount-coins[0]、amount-coins[1]+1、 amount-coins[2。
         * 故 f[x] = min( f[amount-coins[0]], f[amount-coins[1]], f[amount-coins[2]] )
         */
        int len = coins.length;
        int []dp = new int[amount + 1]; //0,1....amount 共amount+1个
        dp[0] = 0;
        for (int i = 1; i <= amount; ++i) {
            dp[i] = Integer.MAX_VALUE;
            for (int j = 0; j < len; ++j) {
                if(i >= coins[j] && dp[i - coins[j]] + 1 < dp[i] && dp[i - coins[j]] != Integer.MAX_VALUE){
                    dp[i] = dp[i - coins[j]] + 1;
                }
            }
        }
        if(dp[amount] == Integer.MAX_VALUE){
            return -1;
        }
        return dp[amount];
    }

    public static void main(String[] args) {
        int []num = {2,5,7};
        System.out.println(coinChange(num, 27));
    }
}
